﻿using wwl.Domain.Entities.Common;

namespace wwl.Domain.Entities.Rbac
{
  /// <summary>
  /// 角色聚合根（DDD 核心领域实体）
  /// 属于权限模块（Rbac）的核心聚合根，承载权限分配和访问控制的核心业务逻辑
  /// 聚合边界：角色定义 + 关联权限集合 + 关联用户集合，构成完整的角色权限上下文
  /// 设计对齐 Camunda 的 act_id_group 概念，将角色视为特殊的用户分组实现
  /// </summary>
  public class Role : BaseEntity, ITenantAware
  {
    /// <summary>
    /// 角色编码（领域核心业务标识）
    /// </summary>
    /// <remarks>
    /// 1. 技术友好设计：角色编码采用大写英文和下划线（如 ADMIN、USER_MANAGER），便于程序识别和权限校验。
    /// 2. 全局唯一性：角色编码在系统内全局唯一，作为权限判断的技术标识，与角色名称的业务标识分离。
    /// 3. 稳定性要求：角色编码一旦确定不应轻易修改，因其可能被硬编码在业务逻辑或前端权限控制中。
    /// 4. 多租户扩展：通过 TenantId 实现租户内角色编码唯一性，支持不同租户定义相同的角色编码但不同权限。
    /// </remarks>
    public string RoleCode { get; set; } = string.Empty;

    /// <summary>
    /// 角色名称（业务展示标识）
    /// </summary>
    /// <remarks>
    /// 1. 业务友好设计：角色名称采用中文或业务术语（如"系统管理员"、"用户管理专员"），便于管理员理解和配置。
    /// 2. 可读性优先：128字符长度支持详细的角色描述，明确角色的职责范围和业务场景。
    /// 3. 灵活性支持：角色名称可随时修改，不影响已有的权限配置和业务逻辑。
    /// 4. 多语言考虑：预留足够长度支持多语言角色名称，适应国际化业务需求。
    /// </remarks>
    public string RoleName { get; set; } = string.Empty;

    /// <summary>
    /// 角色类型（系统内置与业务自定义分类）
    /// </summary>
    /// <remarks>
    /// 1. 权限分级管理：
    ///    - SYSTEM：系统内置角色（如 ADMIN），包含核心系统权限，通常不可删除或修改权限
    ///    - BUSINESS：业务自定义角色，用户根据业务需求创建和配置，权限灵活可调整
    /// 2. 保护机制：系统角色受特殊保护，防止误操作导致系统功能异常，体现"关键配置防误触"设计原则。
    /// 3. 扩展性设计：通过角色类型实现权限管理的灵活性，既保证系统核心功能的稳定性，又支持业务需求的快速响应。
    /// 4. 默认业务类型：新创建角色默认为 BUSINESS 类型，降低系统角色被意外创建的风险。
    /// </remarks>
    public RoleType RoleType { get; set; } = RoleType.BUSINESS;

    /// <summary>
    /// 租户标识（多租户角色隔离）
    /// </summary>
    /// <remarks>
    /// 1. 租户专属角色：每个租户可独立定义自己的角色体系，实现权限模型的完全隔离和定制化。
    /// 2. 系统级角色：TenantId 为 null 表示系统级角色，具备跨租户管理权限，通常分配给平台管理员。
    /// 3. 权限继承：支持租户从系统级角色继承权限模板，快速建立符合自身需求的权限体系。
    /// 4. 数据一致性：通过 TenantId 确保角色与用户、权限的租户归属一致，维护权限体系的完整性。
    /// </remarks>
    public string? TenantId { get; set; }

    /// <summary>
    /// 用户角色关联集合（聚合间关联导航）
    /// </summary>
    /// <remarks>
    /// 1. 反向导航：通过此属性可追溯拥有该角色的所有用户，支持"按角色查用户"的业务场景。
    /// 2. 性能优化：采用延迟加载策略，避免在查询角色信息时自动加载大量用户数据。
    /// 3. 业务分析：支持角色使用情况分析（如哪些角色被广泛使用、哪些角色闲置），为权限优化提供数据支撑。
    /// 4. 级联考虑：角色删除时通过数据库外键实现级联删除用户角色关联，确保数据一致性。
    /// </remarks>
    public virtual ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>();

    /// <summary>
    /// 角色权限关联集合（聚合内核心关联）
    /// </summary>
    /// <remarks>
    /// 1. 权限承载：此集合定义该角色具体拥有的权限列表，是角色功能实现的核心数据。
    /// 2. 即时加载：在查询角色信息时通常需要同时加载权限列表，支持业务场景的完整性需求。
    /// 3. 权限验证：通过遍历此集合可快速判断角色是否拥有特定权限，支撑细粒度的访问控制。
    /// 4. 变更追踪：权限集合的增删改需要严格审计，为权限变更提供完整的操作记录。
    /// </remarks>
    public virtual ICollection<RolePermission> RolePermissions { get; set; } = new List<RolePermission>();
  }

  /// <summary>
  /// 角色类型枚举（DDD 领域枚举，定义角色分类体系）
  /// </summary>
  /// <remarks>
  /// 1. 分类管理：通过类型区分系统核心角色和业务自定义角色，实现差异化的管理策略。
  /// 2. 权限控制：系统角色通常具备更高级别的权限，业务角色的权限范围受租户边界限制。
  /// 3. 生命周期：系统角色随系统部署自动创建，业务角色由用户在系统使用过程中动态创建。
  /// 4. 维护策略：系统角色的维护需要更高权限级别，业务角色可由租户管理员自主管理。
  /// </remarks>
  public enum RoleType
  {
    /// <summary>
    /// 系统内置角色：包含系统运行所必需的核心权限，通常由系统初始化时创建，不允许删除或修改核心权限
    /// </summary>
    SYSTEM,

    /// <summary>
    /// 业务自定义角色：根据业务需求创建的角色，权限配置灵活，支持业务的快速变化和个性化需求
    /// </summary>
    BUSINESS
  }
}